package until;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;


import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
import java.util.TreeMap;
public class SignatureUtils {
   // private static Logger LOGGER = LoggerFactory.getLogger(SignatureUtils.class);

    /**
     * 对内容进行签名
     *
     * @param data          待签名数据
     * @param signSecretKey 签名秘钥
     * @param algorithm     签名算法
     * @return
     */
    public static String sign(byte[] data, String signSecretKey, String algorithm) {
        try {
            Mac mac = Mac.getInstance(algorithm);
            SecretKeySpec secretKeySpec = new SecretKeySpec(signSecretKey.getBytes("UTF-8"), mac.getAlgorithm());
            mac.init(secretKeySpec);
            return Base64.encodeBase64URLSafeString(mac.doFinal(data));
        } catch (Exception e) {
           // LOGGER.error("{} encode error", algorithm, e);
        }
        return null;
    }
//
//    /**
//     * 对内容进行签名
//     *
//     * @param data          待签名数据
//     * @param signSecretKey 签名秘钥
//     * @param algorithm     签名算法
//     * @return 返回签名byte数组
//     */
    public static byte[] signature(byte[] data, String signSecretKey, String algorithm) {
        try {
            Mac mac = Mac.getInstance(algorithm);
            SecretKeySpec secretKeySpec = new SecretKeySpec(signSecretKey.getBytes("UTF-8"), mac.getAlgorithm());
            mac.init(secretKeySpec);
            return mac.doFinal(data);
        } catch (Exception e) {
           // LOGGER.error("{} encode error", algorithm, e);
        }
        return null;
    }
//
//    /**
//     * 生成签名
//     *
//     * @param strText
//     * @return
//     */
    public static String sha256(final String strText) {
        // 返回值
        String strResult = null;
        // 是否是有效字符串
        if (null != strText && strText.length() > 0) {
            try {
                // SHA 加密开始
                // 创建加密对象 并傳入加密類型
                MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
                // 传入要加密的字符串
                messageDigest.update(strText.getBytes());
                // 得到 byte 类型结果
                byte byteBuffer[] = messageDigest.digest();
                // 將 byte 转换为 string
                StringBuffer strHexString = new StringBuffer(byteBuffer.length * 2);
                // 遍歷 byte buffer
                for (int i = 0; i < byteBuffer.length; i++) {
                    String hex = Integer.toHexString(0xff & byteBuffer[i]);
                    if (hex.length() == 1) {
                        strHexString.append('0');
                    }
                    strHexString.append(hex);
                }
                // 得到返回結果
                strResult = strHexString.toString();
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
        }
        return strResult;
    }
//
//    /**
//     * 生成待签名字符串
//     *
//     * @param parameters
//     * @param body
//     * @return
//     */
    public static String buildSignStr(Map<String, String> parameters, String body) {
        Map<String, String> sortedMap = new TreeMap<String,String>(parameters);

        StringBuilder signStrBuilder = new StringBuilder(128);

        for (Map.Entry<String, String> entry : sortedMap.entrySet()) {
            if (entry.getKey().equals("content-Type")) {
                continue;
            }
            if (StringUtils.isNotBlank(entry.getValue())) {
                signStrBuilder.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
            }
        }
        if (signStrBuilder.length() > 1) {
            signStrBuilder.deleteCharAt(signStrBuilder.length() - 1);
        }

        String signStr = signStrBuilder.toString();
        if (StringUtils.isNotBlank(body)) {
            body = body.replaceAll("\\s+", "");
            signStr = signStrBuilder.append(body).toString();
        }

        return signStr;
    }
}
